package model

import (
	"common/helper"
	"database/sql"
	"fmt"
	"github.com/valyala/fasthttp"
	"math"
	"strconv"
)

// 游戏投注记录结构
type GameRecordData struct {
	RowId          string  `db:"row_id" json:"row_id" cbor:"row_id"`
	BillNo         string  `db:"bill_no" json:"bill_no" cbor:"bill_no"`
	PlatformId     string  `db:"platform_id" json:"platform_id" cbor:"platform_id"`
	Uid            string  `db:"uid" json:"uid" cbor:"uid"`
	SettleAmount   float64 `db:"settle_amount" json:"settle_amount" cbor:"settle_amount"`
	BetTime        int64   `db:"bet_time" json:"bet_time" cbor:"bet_time"`
	GameType       string  `db:"game_type" json:"game_type" cbor:"game_type"`
	GameCode       string  `db:"game_code" json:"game_code" cbor:"game_code"`
	BetAmount      float64 `db:"bet_amount" json:"bet_amount" cbor:"bet_amount"`
	ValidBetAmount float64 `db:"valid_bet_amount" json:"valid_bet_amount" cbor:"valid_bet_amount"`
	SettleTime     int64   `db:"settle_time" json:"settle_time" cbor:"settle_time"`
	GameTax        float64 `db:"game_tax" json:"game_tax" cbor:"game_tax"`
	PlatformName   string  `json:"platform_name" db:"platform_name"`
	RouteName      string  `json:"route_name" db:"route_name"`
	Username       string  `json:"username" db:"username"`
	BusinessId     string  `json:"business_id" db:"business_id"`     // 业务员id
	OperatorId     string  `json:"operator_id" db:"operator_id"`     // 渠道id
	OperatorName   string  `json:"operator_name" db:"operator_name"` // 渠道账号
	BusinessName   string  `json:"business_name" db:"business_name"` // 业务员账号
}

// 游戏记录数据
type GameRecordDataRet struct {
	T int64                    `json:"total" cbor:"t"`
	D []CoinRecordData         `json:"d" cbor:"d"`
	S GameRecordStatisticsData `json:"s" cbor:"s"`
}

type GameRecordStatisticsData struct {
	T           int64   `json:"total" cbor:"t"`
	GameRound   int     `json:"game_round" db:"game_round"`
	Running     float64 `json:"running" db:"running"`           // 流水
	Win         float64 `json:"win" db:"win"`                   // 中奖
	Lost        float64 `json:"lost" db:"lost"`                 // 未中奖
	GameTax     float64 `json:"game_tax" db:"game_tax"`         // 游戏税收
	GameWinlost float64 `json:"game_winlost" db:"game_winlost"` // 游戏赢亏
}

func GameRecord(param GameListParam, ctx *fasthttp.RequestCtx) (GameRecordDataRet, error) {
	data := GameRecordDataRet{}

	where := "1=1"
	oderBy := "id"
	oderType := "desc"

	if param.StartTime != "" {
		StartTime, _ := helper.TimeToLocMs(param.StartTime, loc)
		where += " and a.created_at>='" + strconv.FormatInt(StartTime, 10) + "'"
	}
	if param.EndTime != "" {
		EndTime, _ := helper.TimeToLocMs(param.EndTime, loc)
		where += " and a.created_at<'" + strconv.FormatInt(EndTime, 10) + "'"
	}

	if param.Uid != "" {
		where += " and a.uid=" + param.Uid
	}
	if param.PlatformId != "" {
		where += " and a.platform_id=" + param.PlatformId
	}
	if param.Sandbag != "" {
		where += " and a.sandbag=" + param.Sandbag
	}
	if param.OperatorId != "" {
		where += " and b.operator_id=" + param.OperatorId
	}
	if param.BusinessId != "" {
		where += " and b.business_id=" + param.BusinessId
	}
	if param.RouteName != "" {
		where += " and a.route_name='" + param.RouteName + "'"
	}
	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		where += " and b.operator_id=" + loginUser.Operator
	} else if loginUser.Businsess != "" {
		where += " and b.business_id=" + loginUser.Businsess
	}

	where += " and cash_type in(" + strconv.Itoa(helper.TransactionBet) + "," + strconv.Itoa(helper.TransactionPayout) + ")"
	if param.OderBY != "" {
		oderBy = param.OderBY
	}
	if param.OderType != "" {
		oderType = param.OderType
	}
	order := oderBy + " " + oderType

	table := "tbl_balance_transaction"
	join := " left join tbl_member_base as   b on b.uid=a.uid" //玩家表
	//join += " left join tbl_platforms as     c on c.id=a.platform_id" //游戏表
	//join += " left join tbl_operator_info as d on d.id=b.operator_id"       //渠道表
	//join += " left join tbl_business_info as e on e.id=b.business_id"       //业务员表
	//join += " left join tbl_transaction_types as     f on f.id=a.cash_type" //类型表

	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		countJoin := join
		if loginUser.Admin != "" && param.OperatorId == "" && param.BusinessId == "" {
			countJoin = ""
		}
		sfield := "select count(1) t,ifnull(sum(case when cash_type=301 then 1 else 0 end),0) as game_round,ifnull(sum(case when cash_type=301 then amount else 0 end),0) as running,ifnull(sum(case when cash_type=302 then amount else 0 end),0) as game_winlost,ifnull(sum(case when cash_type=302 then game_tax else 0 end),0) as game_tax from " + table + " as a " + countJoin + " where " + where

		err := meta.MerchantDB.Get(&data.S, sfield)
		data.T = data.S.T
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), data.T), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}
	}
	field := "a.*,b.username,b.business_id,b.operator_id"
	query := "select " + field + "  from " + table + " as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)

	err := meta.MerchantDB.Select(&data.D, query)

	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	//获取三方游戏列表
	platform, err := GetPlatformByPid("0")
	platformList := map[string]string{}
	for _, value := range platform {
		platformList[value.ID] = value.Name
	}

	//获取变动类型
	transTypes, err := GetTransTypes()
	transTypesList := map[string]string{}
	for _, value := range transTypes {
		transTypesList[value.ID] = value.Name
	}

	for key, value := range data.D {
		(data.D)[key].PlatformName = platformList[value.PlatformId]
		(data.D)[key].CashName = transTypesList[strconv.Itoa(value.CashType)]
	}

	//统计
	(data.S).Running = math.Abs((data.S).Running)

	(data.S).Win = (data.S).GameWinlost + (data.S).GameTax
	(data.S).Lost = (data.S).Running - (data.S).Win

	(data.S).Win, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", (data.S).Win), 64)   // 保留2位小数
	(data.S).Lost, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", (data.S).Lost), 64) // 保留2位小数

	(data.S).GameWinlost = -(data.S).Lost
	return data, nil
}

// 玩家游戏记录数据
type UserGameRecordDataRet struct {
	T int64                `json:"total" cbor:"t"`
	D []UserGameRecordData `json:"d" cbor:"d"`
}

type UserGameRecordData struct {
	Date         string  `json:"date" db:"date"`
	PlatformId   int     `json:"platform_id" db:"platform_id"`
	PlatformName string  `json:"platform_name" db:"platform_name"`
	Running      float64 `json:"running" db:"running"`           // 流水
	GameWinlost  float64 `json:"game_winlost" db:"game_winlost"` // 游戏赢亏
	GameRate     float64 `json:"game_rate" db:"game_rate"`       // 游戏回报率
	GameTax      float64 `json:"game_tax" db:"game_tax"`         // 游戏税收
	GameRound    int     `json:"game_round" db:"game_round"`     // 游戏局数
}

func UserGameRecord(param GameListParam, ctx *fasthttp.RequestCtx) (UserGameRecordDataRet, error) {
	data := UserGameRecordDataRet{}

	where := "1=1"
	oderBy := "game_rate"
	oderType := "desc"

	if param.Uid != "" {
		where += " and a.uid=" + param.Uid
	}

	if param.StartTime != "" {
		StartTime, _ := helper.TimeToLocMs(param.StartTime, loc)
		where += " and a.created_at>='" + strconv.FormatInt(StartTime, 10) + "'"
	}
	if param.EndTime != "" {
		EndTime, _ := helper.TimeToLocMs(param.EndTime, loc)
		where += " and a.created_at<'" + strconv.FormatInt(EndTime, 10) + "'"
	}

	where += " and cash_type in(" + strconv.Itoa(helper.TransactionBet) + "," + strconv.Itoa(helper.TransactionPayout) + ")"
	if param.OderBY != "" {
		oderBy = param.OderBY
	}
	if param.OderType != "" {
		oderType = param.OderType
	}

	table := "select DATE_FORMAT(FROM_UNIXTIME(created_at/1000), '%Y-%m-%d') as date,platform_id,ifnull(sum(case when cash_type=301 then 1 else 0 end),0) as game_round,ifnull(sum(case when cash_type=301 then -amount else 0 end),0) as running,ifnull(sum(case when cash_type=302 then amount else 0 end),0) as game_winlost,ifnull(sum(case when cash_type=302 then game_tax else 0 end),0) as game_tax from tbl_balance_transaction as a  where " + where + " group by date,platform_id"
	join := ""
	where = "1=1"
	order := oderBy + " " + oderType
	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from (" + table + ") as a " + join + " where " + where

		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {

			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}
		if (data.T) == 0 {
			return data, nil
		}
	}

	field := "a.*" +
		",(CASE WHEN a.running=0 THEN 0 ELSE (a.game_winlost)*100/a.running END) as game_rate"
	query := "select " + field + " from (" + table + ")  as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)

	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil && err != sql.ErrNoRows {

		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	//获取三方游戏列表
	platform, err := GetPlatformByPid("0")
	platformList := map[string]string{}
	for _, value := range platform {
		platformList[value.ID] = value.Name
	}

	for key, value := range data.D {
		(data.D)[key].PlatformName = platformList[strconv.Itoa(value.PlatformId)]
		GameRate := fmt.Sprintf("%.2f", value.GameRate)
		data.D[key].GameRate, _ = strconv.ParseFloat(GameRate, 64)

		value.GameWinlost = value.GameWinlost - value.Running
		GameWinlost := fmt.Sprintf("%.2f", value.GameWinlost)
		data.D[key].GameWinlost, _ = strconv.ParseFloat(GameWinlost, 64)
	}

	return data, nil
}
